package org.chen.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.chen.common.email.dto.EmailConfigDTO;
import org.chen.common.export.dto.ExportConfigDTO;
import org.chen.common.scene.dto.SceneApiConfigDTO;
import org.chen.common.system.SystemConfig;
import org.chen.common.flight.dto.FlightApiConfigDTO;
import org.chen.common.hotel.dto.HotelApiConfigDTO;
import org.chen.common.system.dto.SystemStatusDTO;
import org.chen.system.constant.SystemConfigConstants;
import org.chen.system.mapper.SystemConfigMapper;
import org.chen.system.service.SystemConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SystemConfigServiceImpl implements SystemConfigService {
    
    @Autowired
    private SystemConfigMapper systemConfigMapper;

    @Autowired
    private ApplicationContext applicationContext;

    private static final String[] USER_AGENTS = {
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36 Edg/137.0.0.0"
    };

    @Override
    public FlightApiConfigDTO getFlightApiConfig() {
        List<SystemConfig> configs = systemConfigMapper.selectByConfigType(SystemConfigConstants.CONFIG_TYPE_API);

        FlightApiConfigDTO dto = new FlightApiConfigDTO();
        Map<String, String> configMap = configs.stream()
                .collect(Collectors.toMap(SystemConfig::getConfigKey, SystemConfig::getConfigValue));
        
        dto.setTimeout(Integer.valueOf(configMap.getOrDefault(SystemConfigConstants.API_TIMEOUT, "30000")));
        dto.setRetryCount(Integer.valueOf(configMap.getOrDefault(SystemConfigConstants.API_RETRY_COUNT, "3")));
        dto.setCookie(configMap.get(SystemConfigConstants.API_COOKIE));
        dto.setToken(configMap.get(SystemConfigConstants.API_TOKEN));
        dto.setEnabled(Boolean.valueOf(configMap.getOrDefault(SystemConfigConstants.API_ENABLED, "true")));
        
        return dto;
    }

    @Override
    public HotelApiConfigDTO getHotelApiConfig() {
        List<SystemConfig> configs = systemConfigMapper.selectByConfigType(SystemConfigConstants.CONFIG_TYPE_Hotel_API);

        HotelApiConfigDTO dto = new HotelApiConfigDTO();
        Map<String, String> configMap = configs.stream()
                .collect(Collectors.toMap(SystemConfig::getConfigKey, SystemConfig::getConfigValue));

        dto.setTimeout(Integer.valueOf(configMap.getOrDefault(SystemConfigConstants.Hotel_API_TIMEOUT, "30000")));
        dto.setRetryCount(Integer.valueOf(configMap.getOrDefault(SystemConfigConstants.Hotel_API_RETRY_COUNT, "3")));
        dto.setCookie(configMap.get(SystemConfigConstants.Hotel_API_COOKIE));
        dto.setPhantomToken(configMap.get(SystemConfigConstants.Hotel_API_TOKEN));
        dto.setHotelEnabled(Boolean.valueOf(configMap.getOrDefault(SystemConfigConstants.Hotel_API_ENABLED, "true")));
        dto.setCid(configMap.get(SystemConfigConstants.Hotel_API_CID));
        dto.setAid(configMap.get(SystemConfigConstants.Hotel_API_AID));
        dto.setAgent(configMap.get(SystemConfigConstants.Hotel_API_AGENT));
        dto.setP(configMap.get(SystemConfigConstants.Hotel_API_P));
        dto.setGuid(configMap.get(SystemConfigConstants.Hotel_API_GUID));
        dto.setSid(configMap.get(SystemConfigConstants.Hotel_API_SID));
        dto.setVid(configMap.get(SystemConfigConstants.Hotel_API_VID));

        return dto;
    }

    @Override
    @Transactional
    public void saveHotelApiConfig(HotelApiConfigDTO apiConfig) {
        List<SystemConfig> configs = new ArrayList<>();

        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_Hotel_API,
                SystemConfigConstants.Hotel_API_TIMEOUT, apiConfig.getTimeout().toString(),"酒店API请求超时时间(毫秒)"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_Hotel_API,
                SystemConfigConstants.Hotel_API_RETRY_COUNT, apiConfig.getRetryCount().toString(),"酒店API请求重试次数"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_Hotel_API,
                SystemConfigConstants.Hotel_API_COOKIE, apiConfig.getCookie(),"酒店API请求Cookie"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_Hotel_API,
                SystemConfigConstants.Hotel_API_TOKEN, apiConfig.getPhantomToken(),"酒店API请求Token"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_Hotel_API,
                SystemConfigConstants.Hotel_API_ENABLED, apiConfig.getHotelEnabled().toString(),"酒店API功能是否启用"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_Hotel_API,
                SystemConfigConstants.Hotel_API_P, apiConfig.getP(),"酒店API请求P"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_Hotel_API,
                SystemConfigConstants.Hotel_API_GUID, apiConfig.getGuid(),"酒店API请求Guid"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_Hotel_API,
                SystemConfigConstants.Hotel_API_AGENT, apiConfig.getAgent(),"酒店API请求Agent"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_Hotel_API,
                SystemConfigConstants.Hotel_API_CID, apiConfig.getCid(),"酒店API请求Cid"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_Hotel_API,
                SystemConfigConstants.Hotel_API_AID, apiConfig.getAid(),"酒店API请求Aid"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_Hotel_API,
                SystemConfigConstants.Hotel_API_SID, apiConfig.getSid(),"酒店API请求Sid"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_Hotel_API,
                SystemConfigConstants.Hotel_API_VID, apiConfig.getVid(),"酒店API请求Vid"));

        saveOrUpdateConfigs(configs);
    }

    @Override
    @Transactional
    public void saveSceneApiConfig(SceneApiConfigDTO apiConfig) {
        List<SystemConfig> configs = new ArrayList<>();

        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_SCENE_API,
                SystemConfigConstants.SCENE_API_SID, apiConfig.getSid(), "景点API请求Sid"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_SCENE_API,
                SystemConfigConstants.SCENE_API_CID, apiConfig.getCid(), "景点API请求Cid"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_SCENE_API,
                SystemConfigConstants.SCENE_API_SYSCODE, apiConfig.getSyscode(),"景点API请求SYSCODE"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_SCENE_API,
                SystemConfigConstants.SCENE_API_ENABLED, apiConfig.getSceneEnabled().toString(), "景点API功能是否启用"));
        
        saveOrUpdateConfigs(configs);
    }

    @Override
    public SceneApiConfigDTO getSceneApiConfig() {
        List<SystemConfig> configs = systemConfigMapper.selectByConfigType(SystemConfigConstants.CONFIG_TYPE_SCENE_API);

        SceneApiConfigDTO dto = new SceneApiConfigDTO();
        Map<String, String> configMap = configs.stream()
                .collect(Collectors.toMap(SystemConfig::getConfigKey, SystemConfig::getConfigValue));

        dto.setSyscode(configMap.getOrDefault(SystemConfigConstants.SCENE_API_SYSCODE, "999"));
        dto.setCid(configMap.getOrDefault(SystemConfigConstants.SCENE_API_CID, "09031085319942862668"));
        dto.setSid(configMap.getOrDefault(SystemConfigConstants.SCENE_API_SID, "8888"));
        dto.setSceneEnabled(Boolean.valueOf(configMap.getOrDefault(SystemConfigConstants.SCENE_API_ENABLED, "true")));

        return dto;
    }

    @Override
    @Transactional
    public void saveApiConfig(FlightApiConfigDTO apiConfig) {
        List<SystemConfig> configs = new ArrayList<>();

        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_API,
                SystemConfigConstants.API_TIMEOUT, apiConfig.getTimeout().toString(), "航班API请求超时时间(毫秒)"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_API,
                SystemConfigConstants.API_RETRY_COUNT, apiConfig.getRetryCount().toString(), "航班API请求重试次数"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_API,
                SystemConfigConstants.API_COOKIE, apiConfig.getCookie(), "航班API请求Cookie"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_API,
                SystemConfigConstants.API_TOKEN, apiConfig.getToken(),"航班API请求Token"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_API,
                SystemConfigConstants.API_ENABLED, apiConfig.getEnabled().toString(), "航班API功能是否启用"));

        saveOrUpdateConfigs(configs);
    }
    
    @Override
    public ExportConfigDTO getExportConfig() {
        List<SystemConfig> configs = systemConfigMapper.selectByConfigType(SystemConfigConstants.CONFIG_TYPE_EXPORT);
        
        ExportConfigDTO dto = new ExportConfigDTO();
        Map<String, String> configMap = configs.stream()
                .collect(Collectors.toMap(SystemConfig::getConfigKey, SystemConfig::getConfigValue));
        
        dto.setDefaultPath(configMap.getOrDefault(SystemConfigConstants.EXPORT_DEFAULT_PATH, "./exports"));
        dto.setNameFormat(configMap.getOrDefault(SystemConfigConstants.EXPORT_NAME_FORMAT, "route_date_time"));
        dto.setCustomFormat(configMap.get(SystemConfigConstants.EXPORT_CUSTOM_FORMAT));
        dto.setAutoOpen(Boolean.valueOf(configMap.getOrDefault(SystemConfigConstants.EXPORT_AUTO_OPEN, "true")));
        dto.setFormat(configMap.getOrDefault(SystemConfigConstants.EXPORT_FORMAT, "xlsx"));
        dto.setEncoding(configMap.getOrDefault(SystemConfigConstants.EXPORT_ENCODING, "UTF-8"));
        dto.setMaxFileSize(Long.valueOf(configMap.getOrDefault(SystemConfigConstants.EXPORT_MAX_FILE_SIZE, "10485760")));
        dto.setEnabled(Boolean.valueOf(configMap.getOrDefault(SystemConfigConstants.EXPORT_ENABLED, "true")));
        
        return dto;
    }
    
    @Override
    @Transactional
    public void saveExportConfig(ExportConfigDTO exportConfig) {
        List<SystemConfig> configs = new ArrayList<>();
        
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_EXPORT, 
                SystemConfigConstants.EXPORT_DEFAULT_PATH, exportConfig.getDefaultPath(),"默认导出路径"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_EXPORT, 
                SystemConfigConstants.EXPORT_NAME_FORMAT, exportConfig.getNameFormat(),"文件名格式"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_EXPORT, 
                SystemConfigConstants.EXPORT_AUTO_OPEN, exportConfig.getAutoOpen().toString(),"导出后自动打开"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_EXPORT, 
                SystemConfigConstants.EXPORT_FORMAT, exportConfig.getFormat(),"导出文件格式"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_EXPORT, 
                SystemConfigConstants.EXPORT_ENCODING, exportConfig.getEncoding(),"文件编码"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_EXPORT, 
                SystemConfigConstants.EXPORT_MAX_FILE_SIZE, exportConfig.getMaxFileSize().toString(),"最大文件大小(字节)"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_EXPORT, 
                SystemConfigConstants.EXPORT_ENABLED, exportConfig.getEnabled().toString(),"导出功能是否启用"));
        
        saveOrUpdateConfigs(configs);
    }
    
    @Override
    public EmailConfigDTO getEmailConfig() {
        List<SystemConfig> configs = systemConfigMapper.selectByConfigType(SystemConfigConstants.CONFIG_TYPE_EMAIL);
        
        EmailConfigDTO dto = new EmailConfigDTO();
        Map<String, String> configMap = configs.stream()
                .collect(Collectors.toMap(SystemConfig::getConfigKey, SystemConfig::getConfigValue));
        
        dto.setEnabled(Boolean.valueOf(configMap.getOrDefault(SystemConfigConstants.EMAIL_ENABLED, "false")));
        dto.setFromEmail(configMap.get(SystemConfigConstants.EMAIL_FROM_EMAIL));
        dto.setSmtpHost(configMap.getOrDefault(SystemConfigConstants.EMAIL_SMTP_HOST, "smtp.qq.com"));
        dto.setSmtpPort(Integer.valueOf(configMap.getOrDefault(SystemConfigConstants.EMAIL_SMTP_PORT, "587")));
        dto.setUsername(configMap.get(SystemConfigConstants.EMAIL_USERNAME));
        dto.setPassword(configMap.get(SystemConfigConstants.EMAIL_PASSWORD));
        dto.setSsl(Boolean.valueOf(configMap.getOrDefault(SystemConfigConstants.EMAIL_SSL, "true")));
        
        return dto;
    }
    
    @Override
    @Transactional
    public void saveEmailConfig(EmailConfigDTO emailConfig) {
        List<SystemConfig> configs = new ArrayList<>();

        String password = getEmailConfig().getPassword();

        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_EMAIL, 
                SystemConfigConstants.EMAIL_ENABLED, emailConfig.getEnabled().toString(),"邮件功能是否启用"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_EMAIL, 
                SystemConfigConstants.EMAIL_FROM_EMAIL, emailConfig.getFromEmail(),"发件人邮箱"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_EMAIL, 
                SystemConfigConstants.EMAIL_SMTP_HOST, emailConfig.getSmtpHost(),"SMTP服务器地址"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_EMAIL, 
                SystemConfigConstants.EMAIL_SMTP_PORT, emailConfig.getSmtpPort().toString(),"SMTP服务器端口"));
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_EMAIL, 
                SystemConfigConstants.EMAIL_USERNAME, emailConfig.getUsername(),"SMTP用户名"));
        if (password == null || !StrUtil.hasBlank(emailConfig.getPassword())) {
            if (!emailConfig.getPassword().equals("前端不展示密码")){
                configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_EMAIL,
                        SystemConfigConstants.EMAIL_PASSWORD, emailConfig.getPassword(),"SMTP密码"));
            }
        }
        configs.add(createConfig(SystemConfigConstants.CONFIG_TYPE_EMAIL,
                SystemConfigConstants.EMAIL_SSL, emailConfig.getSsl().toString(),"是否启用SSL"));
        
        saveOrUpdateConfigs(configs);
    }
    
    @Override
    public SystemStatusDTO getSystemStatus() {
        List<SystemConfig> configs = systemConfigMapper.selectByConfigType(SystemConfigConstants.CONFIG_TYPE_SYSTEM);

        SystemStatusDTO dto = new SystemStatusDTO();
        Map<String, String> configMap = configs.stream()
                .collect(Collectors.toMap(SystemConfig::getConfigKey, SystemConfig::getConfigValue));

        // 系统版本
        dto.setVersion(configMap.getOrDefault(SystemConfigConstants.SYSTEM_VERSION, "1.0.0"));
        
        // 系统状态
        dto.setStatus(configMap.getOrDefault(SystemConfigConstants.SYSTEM_STATUS, "running"));
        
        // 最后更新时间
        dto.setLastUpdate(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

        return dto;
    }

    @Override
    public Boolean testEmailSending(String testEmail) {
        try {
            EmailNotificationService emailService = applicationContext.getBean(EmailNotificationService.class);
            return emailService.sendTestEmail(testEmail);
        } catch (Exception e) {
            log.error("测试邮件发送失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional
    public void resetAllConfigs() {
        // 删除所有配置
        systemConfigMapper.delete(new LambdaQueryWrapper<>());
        
        // 恢复默认配置
        initDefaultConfigs();
    }
    
    // === 私有方法 ===
    
    private SystemConfig createConfig(String configType, String configKey, String configValue, String description) {
        SystemConfig config = new SystemConfig();
        config.setConfigType(configType);
        config.setConfigKey(configKey);
        config.setConfigValue(configValue);
        config.setDescription(description);
        config.setEnabled(true);
        config.setCreateTime(LocalDateTime.now());
        config.setUpdateTime(LocalDateTime.now());
        return config;
    }
    
    private void saveOrUpdateConfigs(List<SystemConfig> configs) {
        for (SystemConfig config : configs) {
            SystemConfig existing = systemConfigMapper.selectByTypeAndKey(
                    config.getConfigType(), config.getConfigKey());
            
            if (existing != null) {
                existing.setConfigValue(config.getConfigValue());
                systemConfigMapper.updateById(existing);
            } else {
                systemConfigMapper.insert(config);
            }
        }
    }
    
    private void initDefaultConfigs() {
        // 初始化默认配置的逻辑
        FlightApiConfigDTO defaultApiConfig = new FlightApiConfigDTO();
        defaultApiConfig.setTimeout(30000);
        defaultApiConfig.setRetryCount(3);
        defaultApiConfig.setEnabled(true);
        saveApiConfig(defaultApiConfig);

        // 初始化默认配置的酒店API
        HotelApiConfigDTO defaultHotelApiConfig = new HotelApiConfigDTO();
        defaultHotelApiConfig.setTimeout(30000);
        defaultHotelApiConfig.setRetryCount(3);
        defaultHotelApiConfig.setHotelEnabled(true);
        defaultHotelApiConfig.setP("34384093271");
        defaultHotelApiConfig.setAgent(USER_AGENTS[new Random().nextInt(USER_AGENTS.length)]);
        defaultHotelApiConfig.setAid("4902");
        defaultHotelApiConfig.setGuid("09031085319942862668");
        defaultHotelApiConfig.setSid("130727");
        defaultHotelApiConfig.setVid("1743501440388.a3d4ozuhoWXu");
        defaultHotelApiConfig.setCid("09031085319942862668");
        saveHotelApiConfig(defaultHotelApiConfig);
        
        ExportConfigDTO defaultExportConfig = new ExportConfigDTO();
        defaultExportConfig.setDefaultPath("./exports");
        defaultExportConfig.setNameFormat("route_date_time");
        defaultExportConfig.setAutoOpen(true);
        defaultExportConfig.setFormat("xlsx");
        defaultExportConfig.setEncoding("UTF-8");
        defaultExportConfig.setMaxFileSize(10485760L);
        defaultExportConfig.setEnabled(true);
        saveExportConfig(defaultExportConfig);
        
        EmailConfigDTO defaultEmailConfig = new EmailConfigDTO();
        defaultEmailConfig.setEnabled(false);
        defaultEmailConfig.setSmtpHost("smtp.gmail.com");
        defaultEmailConfig.setSmtpPort(587);
        defaultEmailConfig.setSsl(true);
        saveEmailConfig(defaultEmailConfig);
    }
}